const fs = require('fs');
const path = require('path');

// 配置
const CONFIG = {
  srcDir: './src',
  distDir: './dist',
  entryFile: 'index.html',
  mainJSFile: 'main.js',
  outputFile: 'index.html',
  audioConfigFile: 'audio-config.js',
};

// 环境配置
const ENV_CONFIG = {
  production: {
    envFile: '.env.local',
    description: '生产环境',
    outputDir: 'dist'
  },
  release: {
    envFile: '.env.example.local', 
    description: '发布环境',
    outputDir: 'dist-release'
  }
};

// 解析命令行参数
function parseArgs() {
  const args = process.argv.slice(2);
  const mode = args[0] || 'production';
  
  if (!ENV_CONFIG[mode]) {
    console.error(`❌ 未知模式: ${mode}`);
    console.log('💡 可用模式: production, release');
    process.exit(1);
  }
  
  return {
    mode,
    ...ENV_CONFIG[mode]
  };
}

// MIME 类型映射
function getMimeType(filePath) {
  const ext = path.extname(filePath).toLowerCase();
  const mimeTypes = {
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.png': 'image/png',
    '.gif': 'image/gif',
    '.svg': 'image/svg+xml',
    '.webp': 'image/webp',
    '.ico': 'image/x-icon',
    '.bmp': 'image/bmp',
    '.mp3': 'audio/mpeg',
    '.wav': 'audio/wav',
    '.ogg': 'audio/ogg',
    '.m4a': 'audio/mp4',
    '.aac': 'audio/aac',
    '.flac': 'audio/flac',
    '.weba': 'audio/webm'
  };
  
  return mimeTypes[ext] || 'application/octet-stream';
}

// 文件转 Base64
function fileToBase64(filePath) {
  try {
    const mimeType = getMimeType(filePath);
    const fileBuffer = fs.readFileSync(filePath);
    const base64 = fileBuffer.toString('base64');
    console.log(`   ✅ 成功转换: ${path.basename(filePath)} (${Math.round(fileBuffer.length / 1024)} KB)`);
    return `data:${mimeType};base64,${base64}`;
  } catch (error) {
    console.error(`   ❌ 转换失败: ${filePath}`, error.message);
    return null;
  }
}

// 解析资源路径为绝对路径
function resolveResourcePath(resourcePath, baseDir, currentFileDir) {
  if (resourcePath.startsWith('data:')) {
    return null;
  }
  
  let fullPath;
  if (resourcePath.startsWith('/')) {
    fullPath = path.join(baseDir, resourcePath);
  } else {
    fullPath = path.resolve(currentFileDir, resourcePath);
  }
  
  if (fs.existsSync(fullPath)) {
    return fullPath;
  } else {
    console.error(`   ❌ 文件不存在: ${fullPath}`);
    return null;
  }
}

// 处理音频配置文件 - 完全重写 nameMapping 处理
function processAudioConfig(configPath, baseDir) {
  console.log(`🎵 处理音频配置文件: ${path.relative(baseDir, configPath)}`);
  
  const configContent = fs.readFileSync(configPath, 'utf8');
  const configDir = path.dirname(configPath);
  
  // 提取配置对象
  const configMatch = configContent.match(/window\.AUDIO_CONFIG\s*=\s*({[\s\S]*?});/);
  if (!configMatch) {
    console.error('❌ 无法解析音频配置文件格式');
    return null;
  }
  
  let configStr = configMatch[1];
  let basePath = 'audio/';
  
  // 提取 basePath
  const basePathMatch = configStr.match(/basePath:\s*'([^']*)'/);
  if (basePathMatch) {
    basePath = basePathMatch[1];
    console.log(`   📁 音频基础路径: ${basePath}`);
  }

  // 完全重写 nameMapping 处理逻辑
  const nameMappingStart = configStr.indexOf('nameMapping:');
  if (nameMappingStart !== -1) {
    console.log(`   🔍 处理 nameMapping...`);
    
    // 找到 nameMapping 对象的开始和结束位置
    let braceCount = 0;
    let nameMappingEnd = nameMappingStart;
    let inNameMapping = false;
    
    for (let i = nameMappingStart; i < configStr.length; i++) {
      const char = configStr[i];
      if (char === '{' && !inNameMapping) {
        inNameMapping = true;
        braceCount = 1;
      } else if (char === '{' && inNameMapping) {
        braceCount++;
      } else if (char === '}' && inNameMapping) {
        braceCount--;
        if (braceCount === 0) {
          nameMappingEnd = i + 1;
          break;
        }
      }
    }
    
    if (nameMappingEnd > nameMappingStart) {
      const nameMappingSection = configStr.substring(nameMappingStart, nameMappingEnd);
      
      // 使用更精确的正则表达式匹配键值对
      const nameMappingRegex = /(['"])([^'"]+)\1\s*:\s*['"]([^'"]+)['"]/g;
      let match;
      let processedCount = 0;
      let errorCount = 0;
      
      let newNameMappingSection = nameMappingSection;
      
      while ((match = nameMappingRegex.exec(nameMappingSection)) !== null) {
        const fullMatch = match[0];
        const name = match[2];
        const audioPath = match[3];
        
        // 跳过注释行
        if (audioPath.includes('//')) {
          continue;
        }
        
        // 构建完整路径
        const fullAudioPath = path.join(basePath, audioPath);
        const fullPath = resolveResourcePath(fullAudioPath, baseDir, configDir);
        
        if (fullPath) {
          const base64 = fileToBase64(fullPath);
          if (base64) {
            // 替换原始键值对
            const newPair = `'${name}': '${base64}'`;
            newNameMappingSection = newNameMappingSection.replace(fullMatch, newPair);
            processedCount++;
            console.log(`     👤 ${name} -> ${audioPath}`);
          } else {
            errorCount++;
          }
        } else {
          errorCount++;
        }
      }
      
      console.log(`   📊 nameMapping: 成功 ${processedCount} 个, 失败 ${errorCount} 个`);
      
      // 替换整个 nameMapping 部分
      configStr = configStr.substring(0, nameMappingStart) + 
                  newNameMappingSection + 
                  configStr.substring(nameMappingEnd);
    }
  }
  
  // 处理 randomPool 数组
  const randomPoolMatch = configStr.match(/randomPool:\s*\[([\s\S]*?)\]/);
  if (randomPoolMatch) {
    console.log(`   🔍 处理 randomPool...`);
    const randomPoolContent = randomPoolMatch[1];
    let processedCount = 0;
    let errorCount = 0;
    
    const processedRandomPool = randomPoolContent.replace(/'([^']+)'/g, (match, audioPath) => {
      // 跳过注释行
      if (audioPath.includes('//')) {
        return match;
      }
      
      // 构建完整路径
      const fullAudioPath = path.join(basePath, audioPath);
      const fullPath = resolveResourcePath(fullAudioPath, baseDir, configDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          processedCount++;
          console.log(`     🎲 randomPool -> ${audioPath}`);
          return `'${base64}'`;
        } else {
          errorCount++;
        }
      } else {
        errorCount++;
      }
      return match;
    });
    
    console.log(`   📊 randomPool: 成功 ${processedCount} 个, 失败 ${errorCount} 个`);
    configStr = configStr.replace(randomPoolMatch[0], `randomPool: [${processedRandomPool}]`);
  }
  
  // 处理 audioSequence 数组
  const audioSequenceMatch = configStr.match(/audioSequence:\s*\[([\s\S]*?)\]/);
  if (audioSequenceMatch) {
    console.log(`   🔍 处理 audioSequence...`);
    const audioSequenceContent = audioSequenceMatch[1];
    let processedCount = 0;
    let errorCount = 0;
    
    const processedAudioSequence = audioSequenceContent.replace(/'([^']+)'/g, (match, audioPath) => {
      // 跳过注释行
      if (audioPath.includes('//')) {
        return match;
      }
      
      // 构建完整路径
      const fullAudioPath = path.join(basePath, audioPath);
      const fullPath = resolveResourcePath(fullAudioPath, baseDir, configDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          processedCount++;
          console.log(`     📋 audioSequence -> ${audioPath}`);
          return `'${base64}'`;
        } else {
          errorCount++;
        }
      } else {
        errorCount++;
      }
      return match;
    });
    
    console.log(`   📊 audioSequence: 成功 ${processedCount} 个, 失败 ${errorCount} 个`);
    configStr = configStr.replace(audioSequenceMatch[0], `audioSequence: [${processedAudioSequence}]`);
  }
  
  // 处理 defaultAudio
  const defaultAudioMatch = configStr.match(/defaultAudio:\s*'([^']+)'/);
  if (defaultAudioMatch) {
    const audioPath = defaultAudioMatch[1];
    // 跳过注释行
    if (!audioPath.includes('//')) {
      // 构建完整路径
      const fullAudioPath = path.join(basePath, audioPath);
      const fullPath = resolveResourcePath(fullAudioPath, baseDir, configDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          console.log(`   ✅ 默认音频: ${fullAudioPath}`);
          configStr = configStr.replace(defaultAudioMatch[0], `defaultAudio: '${base64}'`);
        }
      }
    }
  }
  
  // 移除 basePath（因为现在都是 Base64 内联数据）
  configStr = configStr.replace(/basePath:\s*'[^']*',\s*/, '');
  
  // 生成最终的音频配置文件内容
  const finalConfig = `// audio-config.js - 音频管理器配置文件（Base64版本）
// 注意：此文件包含隐私信息，请勿提交到公共仓库

window.AUDIO_CONFIG = ${configStr};`;
  
  return finalConfig;
}

// 环境变量处理函数
function replaceEnvVariables(content, envVars) {
  let result = content;
  
  result = result.replace(
    /process\.env\.([A-Z_][A-Z0-9_]*)/gi,
    (match, envVar) => {
      const value = envVars[envVar];
      if (value !== undefined) {
        return value;
      }
      console.warn(`⚠️  环境变量未定义: ${envVar}`);
      return 'undefined';
    }
  );
  
  result = result.replace(
    /import\.meta\.env\.([A-Z_][A-Z0-9_]*)/gi,
    (match, envVar) => {
      const value = envVars[envVar];
      if (value !== undefined) {
        return value;
      }
      console.warn(`⚠️  环境变量未定义: ${envVar}`);
      return 'undefined';
    }
  );
  
  result = result.replace(
    /{{\s*([A-Z_][A-Z0-9_]*)\s*}}/g,
    (match, envVar) => {
      const value = envVars[envVar];
      if (value !== undefined) {
        return value;
      }
      console.warn(`⚠️  环境变量未定义: ${envVar}`);
      return '';
    }
  );
  
  return result;
}

// 环境变量加载函数
function loadEnvVariables(envFile, mode) {
  const env = {};
  
  const envFilePath = path.join(process.cwd(), envFile);
  if (fs.existsSync(envFilePath)) {
    console.log(`📝 加载环境变量: ${envFile} (${mode}模式)`);
    const envContent = fs.readFileSync(envFilePath, 'utf8');
    let count = 0;
    envContent.split('\n').forEach(line => {
      const trimmed = line.trim();
      if (trimmed && !trimmed.startsWith('#')) {
        const match = trimmed.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/);
        if (match) {
          env[match[1]] = match[2];
          count++;
          console.log(`   ${match[1]} = ${match[2]}`);
        }
      }
    });
    console.log(`✅ 共加载 ${count} 个环境变量`);
  } else {
    console.error(`❌ 环境变量文件不存在: ${envFile}`);
    console.log(`💡 请创建 ${envFile} 文件`);
    process.exit(1);
  }
  
  return env;
}

// 处理 CSS 内容
function processCSS(cssContent, baseDir, currentFileDir) {
  const processedFiles = [];
  const result = cssContent.replace(
    /url\(['"]?([^'")]+)['"]?\)/g,
    (match, resourcePath) => {
      const fullPath = resolveResourcePath(resourcePath, baseDir, currentFileDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          const relativePath = path.relative(baseDir, fullPath);
          processedFiles.push(relativePath);
          return `url("${base64}")`;
        }
      }
      return match;
    }
  );
  
  if (processedFiles.length > 0) {
    console.log(`🎨 CSS内联资源:`);
    processedFiles.forEach(file => {
      console.log(`   📄 ${file}`);
    });
    console.log(`   共 ${processedFiles.length} 个资源`);
  }
  
  return result;
}

// 处理 HTML 内容
function processHTML(htmlContent, baseDir, currentFileDir) {
  let result = htmlContent;
  const processedImages = [];
  const processedAudios = [];
  
  result = result.replace(
    /<img([^>]+)src="([^"]+)"([^>]*)/gi,
    (match, before, src, after) => {
      const fullPath = resolveResourcePath(src, baseDir, currentFileDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          const relativePath = path.relative(baseDir, fullPath);
          processedImages.push(relativePath);
          return `<img${before}src="${base64}"${after}`;
        }
      }
      return match;
    }
  );
  
  result = result.replace(
    /<(audio|source)([^>]+)src="([^"]+)"([^>]*)/gi,
    (match, tag, before, src, after) => {
      const fullPath = resolveResourcePath(src, baseDir, currentFileDir);
      if (fullPath) {
        const base64 = fileToBase64(fullPath);
        if (base64) {
          const relativePath = path.relative(baseDir, fullPath);
          processedAudios.push(relativePath);
          return `<${tag}${before}src="${base64}"${after}`;
        }
      }
      return match;
    }
  );
  
  if (processedImages.length > 0) {
    console.log(`🖼️ HTML内联图片:`);
    processedImages.forEach(file => {
      console.log(`   📄 ${file}`);
    });
    console.log(`   共 ${processedImages.length} 个图片`);
  }
  
  if (processedAudios.length > 0) {
    console.log(`🎵 HTML内联音频:`);
    processedAudios.forEach(file => {
      console.log(`   📄 ${file}`);
    });
    console.log(`   共 ${processedAudios.length} 个音频`);
  }
  
  return result;
}

// 处理 JS 内容
function processJS(jsContent, baseDir, currentFileDir, envVars, mode) {
  let result = jsContent;
  const processedResources = [];
  
  const envVarsInJS = [];
  result = result.replace(
    /(process\.env\.\w+|import\.meta\.env\.\w+)/gi,
    (match) => {
      envVarsInJS.push(match);
      return match;
    }
  );
  
  const uniqueEnvVars = [...new Set(envVarsInJS)];
  if (uniqueEnvVars.length > 0) {
    console.log(`🔧 JS环境变量引用:`);
    uniqueEnvVars.forEach(envVar => {
      console.log(`   📄 ${envVar}`);
    });
    console.log(`   共 ${uniqueEnvVars.length} 个环境变量引用`);
  }
  
  result = replaceEnvVariables(result, envVars);
  
  const patterns = [
    /new\s+Audio\(\s*['"]([^'"]+)['"]\s*\)/g,
    /\.src\s*=\s*['"]([^'"]+)['"]/g,
    /\.createElement\('(audio|img)'\)[^.]*\.src\s*=\s*['"]([^'"]+)['"]/gi
  ];
  
  patterns.forEach(pattern => {
    result = result.replace(pattern, (match, ...groups) => {
      const resourcePath = groups.find(g => typeof g === 'string' && !['audio', 'img'].includes(g));
      if (resourcePath) {
        const fullPath = resolveResourcePath(resourcePath, baseDir, currentFileDir);
        if (fullPath) {
          const base64 = fileToBase64(fullPath);
          if (base64) {
            const relativePath = path.relative(baseDir, fullPath);
            processedResources.push(relativePath);
            return match.replace(resourcePath, base64);
          }
        }
      }
      return match;
    });
  });
  
  if (processedResources.length > 0) {
    console.log(`📜 JS内联资源:`);
    processedResources.forEach(file => {
      console.log(`   📄 ${file}`);
    });
    console.log(`   共 ${processedResources.length} 个资源引用`);
  }
  
  return result;
}

// 检查文件是否存在
function checkRequiredFiles() {
  const { srcDir, entryFile, mainJSFile, audioConfigFile } = CONFIG;
  const requiredFiles = [
    path.join(srcDir, entryFile),
    path.join(srcDir, mainJSFile),
    path.join(srcDir, audioConfigFile)
  ];
  
  const missingFiles = requiredFiles.filter(file => !fs.existsSync(file));
  
  if (missingFiles.length > 0) {
    console.error('❌ 缺少必需文件:');
    missingFiles.forEach(file => {
      console.error(`   - ${file}`);
    });
    return false;
  }
  
  return true;
}

// 主构建函数
function build() {
  console.log('🚀 开始构建...\n');
  
  const { mode, envFile, description, outputDir } = parseArgs();
  console.log(`🎯 构建模式: ${mode} - ${description}\n`);
  
  const { srcDir, entryFile, mainJSFile, outputFile, audioConfigFile } = CONFIG;
  
  if (!checkRequiredFiles()) {
    process.exit(1);
  }
  
  const envVars = loadEnvVariables(envFile, mode);
  
  const finalOutputDir = outputDir;
  
  if (fs.existsSync(finalOutputDir)) {
    console.log(`🗑️  清理目录: ${finalOutputDir}`);
    fs.rmSync(finalOutputDir, { recursive: true });
  }
  fs.mkdirSync(finalOutputDir, { recursive: true });
  
  const audioConfigPath = path.join(srcDir, audioConfigFile);
  console.log(`\n🎵 处理音频配置文件...`);
  const audioConfigContent = processAudioConfig(audioConfigPath, srcDir);
  
  if (!audioConfigContent) {
    console.error('❌ 音频配置文件处理失败');
    process.exit(1);
  }
  
  console.log(`✅ 音频配置文件处理完成`);
  
  const entryFilePath = path.join(srcDir, entryFile);
  let htmlContent = fs.readFileSync(entryFilePath, 'utf8');
  const entryDir = path.dirname(entryFilePath);
  
  console.log(`\n📄 处理主文件: ${entryFile}`);
  
  htmlContent = replaceEnvVariables(htmlContent, envVars);
  
  htmlContent = processHTML(htmlContent, srcDir, entryDir);
  
  console.log(`\n🔗 内联音频配置到 HTML`);
  htmlContent = htmlContent.replace('</head>', `<script>${audioConfigContent}</script>\n</head>`);
  
  htmlContent = htmlContent.replace(
    /<link[^>]+href="([^"]+\.css)"[^>]*>/gi,
    (match, cssPath) => {
      const fullPath = resolveResourcePath(cssPath, srcDir, entryDir);
      if (fullPath) {
        const relativePath = path.relative(srcDir, fullPath);
        console.log(`\n🎨 处理CSS文件: ${relativePath}`);
        let cssContent = fs.readFileSync(fullPath, 'utf8');
        const cssDir = path.dirname(fullPath);
        cssContent = processCSS(cssContent, srcDir, cssDir);
        return `<style>${cssContent}</style>`;
      }
      return match;
    }
  );
  
  const mainJSPath = path.join(srcDir, mainJSFile);
  if (fs.existsSync(mainJSPath)) {
    console.log(`\n📜 处理主JS文件: ${mainJSFile}`);
    let mainJSContent = fs.readFileSync(mainJSPath, 'utf8');
    const mainJSDir = path.dirname(mainJSPath);
    mainJSContent = processJS(mainJSContent, srcDir, mainJSDir, envVars, mode);
    
    htmlContent = htmlContent.replace(
      /<script[^>]*src=["'][^"']*main\.js["'][^>]*><\/script>/i,
      `<script>${mainJSContent}</script>`
    );
  }
  
  htmlContent = htmlContent.replace(
    /<script[^>]+src="([^"]+\.js)"[^>]*><\/script>/gi,
    (match, jsPath) => {
      if (jsPath.includes('main.js')) {
        return match;
      }
      
      const fullPath = resolveResourcePath(jsPath, srcDir, entryDir);
      if (fullPath) {
        const relativePath = path.relative(srcDir, fullPath);
        console.log(`\n📜 处理JS文件: ${relativePath}`);
        let jsContent = fs.readFileSync(fullPath, 'utf8');
        const jsDir = path.dirname(fullPath);
        jsContent = processJS(jsContent, srcDir, jsDir, envVars, mode);
        return `<script>${jsContent}</script>`;
      }
      return match;
    }
  );
  
  const inlineCSSMatches = htmlContent.match(/<style[^>]*>([\s\S]*?)<\/style>/gi);
  if (inlineCSSMatches && inlineCSSMatches.length > 0) {
    console.log(`\n🎨 处理内联CSS: ${inlineCSSMatches.length} 处`);
    htmlContent = htmlContent.replace(
      /<style[^>]*>([\s\S]*?)<\/style>/gi,
      (match, cssContent) => {
        const processedCSS = processCSS(cssContent, srcDir, entryDir);
        return `<style>${processedCSS}</style>`;
      }
    );
  }
  
  const inlineJSMatches = htmlContent.match(/<script[^>]*>([\s\S]*?)<\/script>/gi);
  if (inlineJSMatches && inlineJSMatches.length > 0) {
    console.log(`\n📜 处理内联JS: ${inlineJSMatches.length} 处`);
    htmlContent = htmlContent.replace(
      /<script[^>]*>([\s\S]*?)<\/script>/gi,
      (match, jsContent) => {
        const processedJS = processJS(jsContent, srcDir, entryDir, envVars, mode);
        return `<script>${processedJS}</script>`;
      }
    );
  }
  
  if (!htmlContent.includes(`<script>`) || 
      (htmlContent.includes(`src="main.js"`) || htmlContent.includes(`src='main.js'`))) {
    const mainJSPath = path.join(srcDir, mainJSFile);
    if (fs.existsSync(mainJSPath)) {
      console.log(`\n📜 插入主JS: ${mainJSFile}`);
      let mainJSContent = fs.readFileSync(mainJSPath, 'utf8');
      const mainJSDir = path.dirname(mainJSPath);
      mainJSContent = processJS(mainJSContent, srcDir, mainJSDir, envVars, mode);
      htmlContent = htmlContent.replace('</body>', `<script>${mainJSContent}</script></body>`);
    }
  }
  
  const outputPath = path.join(finalOutputDir, outputFile);
  fs.writeFileSync(outputPath, htmlContent);
  
  const fileSize = (fs.statSync(outputPath).size / 1024 / 1024).toFixed(2);
  
  console.log('\n✅ 构建完成！');
  console.log(`📁 输出目录: ${finalOutputDir}/`);
  console.log(`📄 输出文件: ${outputFile}`);
  console.log(`📊 文件大小: ${fileSize} MB`);
  console.log(`🌐 可直接在浏览器中打开使用`);
  console.log(`\n💡 使用方法:`);
  console.log(`   npm run build          # 生产环境`);
  console.log(`   npm run build:release  # 发布环境`);
}

// 执行构建
build();
